home *** CD-ROM | disk | FTP | other *** search
/ Network Support Library / RoseWare - Network Support Library.iso / apidev / apiasm.exe / API.ASM
Assembly Source File  |  1992-08-09  |  45KB  |  1,368 lines

  1. ;--------------------------------------------------
  2. ;
  3. ;             JX
  4. ;
  5. ;--------------------------------------------------
  6.  
  7. comment #
  8.  
  9. keywords: CXI API POPUP ASM
  10.  
  11. SAMPLE asm source code for a popup interface between a
  12. pc user and a mainframe coax-connected host, via the CXI API.
  13. This allows a program to process screens and keys before
  14. passing them through. Uploaded as a self-extracting EXE.
  15.  
  16. Unlike simpler programs, this type of program in active thoughout
  17. the session, and must continually keep the screen updated while
  18. passing along translated keystrokes to the host when the host
  19. is not busy. A reset can be sent while the host is busy.
  20.  
  21. This is not a working program. Code which was specific to the
  22. original application has been removed. The original program
  23. provided allowed a mainframe reporting program to print directly
  24. on the pc using specially formatted screens.
  25.  
  26. The current hotkey is both shift keys together.
  27.  
  28. The 'outkb' routine is untested on 8088 machines...
  29.  
  30. See the cautions marked by double-semi flags (';;')
  31.  
  32.         #
  33. ;-------------------------------------------------
  34.  
  35.               ;bios seg
  36. bios_seg      segment at 40h
  37.               org     17h
  38. kbflag        db      ?
  39.               org     1Ah
  40. kbhead        dw      ?       ;buffer head
  41. kbtail        dw      ?       ;buffer tail
  42. kbbuf         dw      16 dup (?)  ;orig\only buf
  43.               org     63h
  44. addr_crtc     dw      ?       ;crtc base
  45.               org     87h
  46. ega_info      db      ?       ;ega info byte
  47. bios_seg      ends
  48. ;-------------------------------------------------
  49.  
  50. code          segment para public 'code'
  51.               assume  cs:code, ds:code
  52.               org     100h
  53. begin:        jmp     install
  54.               db      'JX 01- cxi screen capture'
  55. ;--------------------------------------------------
  56.  
  57. adapter       db      0
  58. apicall       equ     <int 111>  ;"saves only cs,ds,es,bp,ss,sp"
  59. areasw        db      0
  60. bioseg        dw      40h
  61. busy10        db      0
  62. busy13        db      0
  63. critaddr      dw      0
  64. crtc          dw      0
  65. cseg          dw      0
  66. curloc        dw      0
  67. curloc2       dw      0
  68. curpos2       dw      0
  69. curtyp2       dw      0
  70. dataloc       dw      0       ;bufloc for data start
  71. dos_seg       dw      0       ;seg of internal dos flags
  72. dos_version   dw      0       ;dos version number
  73. indosaddr     dw      0       ;offset of indos flag
  74. jxactive      db      0
  75. kbstart       dw      0
  76. kbend         dw      0
  77. muxid         equ     44
  78. mypsp         dw      0
  79. my_style      dw      0
  80. oldint8       dw      0,0     ;tik
  81. oldint9       dw      0,0     ;kb
  82. oldint28      dw      0,0     ;idle
  83. oldint2f      dw      0,0     ;mux
  84. pop_request   db      0
  85. popped        db      0
  86. popoutsw      db      0
  87. prevscan      db      0,0
  88. resetsw       db      0
  89. savess        dw      0       ;must be in cs:
  90. savesp        dw      0       ;"
  91. tmodd         dw      0,0
  92. uninsw        db      0
  93. unloadsw      db      0
  94. vid_page      db      0
  95. vidseg        dw      0
  96. ;..................................................
  97.  
  98.               ;aid keys
  99. aidlist       db      105, 112, 113   ;clr, pa1, pa2
  100.                       ;pf1-24
  101.               db      120,121,122,123,124,126,126,127,128,129,130,131
  102.               db      133,134,135,136,137,138,139,140,141,142,143,144
  103. aidlistlen    equ     $-aidlist
  104. ;------------------------------------------------------------
  105.  
  106.               ;bug on some 286s:
  107.               ;if ints are disabled and the flags on the stack are also
  108.               ;disabled, a popf may allow one int after the popf
  109.               ;Use this macro instead
  110.  
  111. popff         macro
  112.               push    cs
  113.               call    iiret  ;any iret
  114.               endm
  115. ;..................................................
  116.  
  117.               ;long 'jmp if equal'
  118. jmpe          macro   x
  119.               local   tt
  120.               jne     tt
  121.               jmp     &x
  122. tt:
  123.               endm
  124. ;..................................................
  125.  
  126. jmpne         macro   x
  127.               local   tt
  128.               je      tt
  129.               jmp     &x
  130. tt:
  131.               endm
  132. ;..................................................
  133.  
  134. mypusha       macro
  135.               irp     x, <ax, bx, cx, dx, di, si, ds, es, bp>
  136.               push    x
  137.               endm
  138.               endm
  139. ;.............................................................
  140. mypopa        macro
  141.               irp     x, <bp, es, ds, si, di, dx, cx, bx, ax>
  142.               pop     x
  143.               endm
  144.               endm
  145. ;..........................................................
  146.  
  147. esds          macro
  148.               push    ds
  149.               pop     es
  150.               endm
  151. ;..........................................................
  152.  
  153.               ;load literal addr with inline constant
  154. laddr         macro   r, l
  155.               local   tt
  156.               mov     &r, offset $ +5
  157.               jmp     short tt
  158.               db      &l
  159. tt:
  160.               endm
  161. ;--------------------------------------------------
  162. ;--------------------------------------------------
  163.  
  164. restart:
  165.               ;popup entry point- after lo-level activation
  166.               esds                    ;set es=ds
  167.               call    pushscr2        ;save screen
  168.               call    clrscr          ;clear screen
  169. mywait:
  170.               ;idle loop entry point
  171.               int     28h             ;idle call dos
  172.  
  173.               cmp     popoutsw, 0     ;hotkey back to dos
  174.               je      @f              ;no
  175.               mov     popoutsw, 0
  176.               jmp     popout
  177. @@:
  178.               call    paint           ;updt display buffer or print
  179.  
  180.               ;process reset key, without testing for busy host
  181.               cmp     resetsw, 0
  182.               je      ss40            ;none
  183.               mov     resetsw, 0
  184.               mov     ax, resetkey    ;send
  185.               call    emit
  186.               call    clr_kb          ;clear all pending keystrokes
  187.               jmp     mywait
  188. ss40:
  189.               ;process non-aid keys, without testing for busy host
  190.               call    tstkey          ;see next key waiting
  191.               jz      mywait          ;none
  192.               cmp     al, 13          ;enter
  193.               je      ss60            ;yes- aid
  194.               or      al, al          ;extended
  195.               jnz     @f              ;no- not aid
  196.               mov     di, offset aidlist  ;search for key in aid list
  197.               xchg    ah, al
  198.               mov     cx, aidlistlen
  199.               esds
  200.               repne   scasb           ;scan
  201.               xchg    ah, al          ;restore
  202.               je      ss60            ;is aid - wait for unlock
  203. @@:
  204.               ;not aid
  205.               call    getkey          ;dequeue the key
  206.               cmp     al, '~'         ;uninstall
  207.               je      @f              ;yes
  208.               call    emit            ;send to buffer
  209.               jmp     ss40            ;get next key
  210. @@:
  211.               ;uninstall
  212.               call    ckvec           ;are we last on all vectors
  213.               jnc     @f              ;yes
  214.               mov     al, 7           ;beep
  215.               int     29h
  216.               jmp     mywait
  217. @@:
  218.               mov     unloadsw, 1
  219.               mov     popped, 0       ;allow recursive pop
  220.               jmp     popout
  221. ss60:
  222.               ;aid key pending
  223.               ;if we are busy, trash the key
  224.  
  225.               call    tstlok          ;kb locked
  226.               jc      ss66            ;yes
  227.               mov     ax, 3           ;wait n/18ths second to be sure
  228.               call    delayx
  229.               mov     ax, 11          ;updt buffer
  230.               apicall
  231.               call    tstlok          ;still unlocked
  232.               jc      ss66            ;no
  233.  
  234.               call    getkey          ;dequeue aid key
  235.               call    emit            ;send it
  236.               jmp     mywait
  237. ss66:
  238.               call    getkey          ;get aid key
  239.               jmp     mywait          ;ignore it
  240. ;--------------------------------------------------
  241.  
  242. paint:
  243.               ;updt buffer
  244.  
  245.               ;updt 3278 buffer
  246.               mov     ax, 11          ;updt buffer
  247.               apicall
  248.  
  249.               ;paint screen
  250.               mov     ax, 10          ;paint screen
  251.               apicall
  252.  
  253.               ;set cursor
  254.               call    tstlok          ;unless locked
  255.               jnc     @f
  256.               ret                     ;locked
  257. @@:
  258.               mov     ax, 4           ;get cursor addr
  259.               apicall
  260.               mov     curloc2, ax     ;painted cursor abs loc
  261.               mov     dx, ax          ;convert to row,col
  262.               mov     ax, 26
  263.               apicall
  264.               cmp     ax, 26          ;no cxi connection
  265.               jne     @f
  266.               mov     ax, 0101h       ;true
  267. @@:
  268.               mov     dx, ax          ;row,col
  269.               dec     dh              ;relative
  270.               dec     dl              ;relative
  271.               call    curpos
  272.               ret
  273. ;--------------------------------------------------
  274.  
  275. tstlok:
  276.               ;stc if kb is locked
  277.               ;busy indicator is statline pos 9 = X
  278.  
  279.               mov     ax, 5           ;read buf char
  280.               mov     dx, 8           ;pos 9
  281.               apicall
  282.               cmp     al, 'X'
  283.               je      lokt
  284.               clc                     ;unlocked
  285.               ret
  286. lokt:
  287.               stc                     ;locked
  288.               ret
  289. ;--------------------------------------------------
  290.  
  291. emit:
  292.               ;send al char to interface
  293.               mov     dx, ax
  294.               xor     dh, dh          ;assume non-extended
  295.               or      al, al
  296.               jnz     @f              ;true
  297.               inc     dh
  298.               mov     dl, ah
  299. @@:
  300.               mov     ax, 6           ;emit key
  301.               apicall
  302.               ret
  303. ;--------------------------------------------------
  304.  
  305. get_kb:
  306.               call    getkey
  307.               jz      get_kb          ;no key avail
  308.               ret
  309. ;..................................................
  310.  
  311. clr_kb:
  312.               call    getkey
  313.               jnz     clr_kb
  314.               ret
  315. ;..................................................
  316.  
  317. tstkey:
  318.               mov     ah, 1           ;any key waiting
  319.               int     16h
  320.               jne     @f              ;yes
  321.               xor     ax, ax          ;zr
  322. @@:           ret
  323. ;..................................................
  324.  
  325. getkey:
  326.               ;return key or zr
  327.               mov     ah, 1           ;any key waiting
  328.               int     16h
  329.               jne     @f              ;yes
  330.               ret
  331. @@:
  332.               mov     ah, 0           ;get key
  333.               int     16h
  334.               cmp     ax, 1515h       ;special prefix
  335.               jne     gk20            ;no
  336.               mov     ah, 1           ;2nd key waiting
  337.               int     16h
  338.               je      getkey          ;no- discard
  339.  
  340.               mov     ah, 0           ;get 2nd key
  341.               int     16h
  342.               xchg    ah, al          ;reformat it
  343. gk20:
  344.               cmp     al, 0e0h        ;ext key
  345.               je      getkey          ;yes- ignore
  346.               or      ax, ax          ;nz
  347.               ret
  348. ;--------------------------------------------------
  349.  
  350. pushscr2:
  351.               ;save user's screen in alternate page ;;
  352.               xor     si, si
  353.               mov     di, si
  354.               add     di, 4096        ;store in page 2
  355.               mov     cx, 4096/2
  356.               mov     es, vidseg
  357.               push    ds
  358.               mov     ds, vidseg
  359.               rep     movsw
  360.               pop     ds
  361.               esds
  362.  
  363.               mov     ah, 3           ;get pos and style
  364.               mov     bh, vid_page
  365.               int     10h
  366.               mov     curpos2, dx
  367.  
  368.               cmp     cl, 0           ;style with emulation disabled
  369.               je      @f              ;yes
  370.               cmp     cl, 7
  371.               ja      @f              ;yes
  372.               or      cx, 80h         ;flag to reset with emulation
  373. @@:
  374.               cmp     adapter, 0      ;mono
  375.               jne     @f              ;no
  376.               mov     cx, 0b0ch
  377. @@:
  378.               mov     curtyp2, cx
  379.               ret
  380. ;..................................................
  381.  
  382. popscr2:
  383.               mov     es, vidseg
  384.               xor     di, di
  385.               mov     si, di
  386.               add     si, 4096
  387.               mov     cx, 4096/2
  388.               push    ds
  389.               mov     ds, vidseg
  390.               rep     movsw
  391.               pop     ds
  392.               esds
  393.  
  394.               mov     dx, curpos2
  395.               call    curpos
  396.  
  397.               mov     cx, curtyp2
  398.               call    show_cx_cursor
  399.               ret
  400. ;--------------------------------------------------
  401. ;--------------------------------------------------
  402.  
  403.               ;KEYBOARD INTERRUPT HANDLER
  404.               ;remap keys for 3270 functions
  405.  
  406. ;f1-12    --> pf1-12
  407. ;alt 1-=      pf1-12
  408. ;ctl f1-12    pf13-24
  409. ;ctl 1-=      pf13-24
  410. ;alt f9       pa1
  411. ;alt f10      pa2
  412. ;alt f11      pa3
  413. ;esc          clear
  414. ;bsp,enter,tab,up,down,left,right,ins,del   == same
  415. ;end          reset
  416. ;home         deleof
  417. ;shift tab    backtab
  418. ;ctl tab      backtab
  419. ;ctl enter    newline
  420. ;.................................................
  421.  
  422.               ;0= transparent
  423.               ;1= ignore
  424. plaintbl:
  425.               dw      6900h           ;1 esc -> clear
  426.               dw      58-2+1 dup(0)   ;2-58 are transparent
  427.               dw      7800h, 7900h    ;59-68 f1-f10
  428.               dw      7a00h, 7b00h    ;f3-4
  429.               dw      7c00h, 7d00h    ;f5-6
  430.               dw      7e00h, 7f00h    ;f7-8
  431.               dw      8000h, 8100h    ;f9-10
  432.               dw      70-69+1 dup(0)  ;69-70 transparent
  433.               dw      4000h           ;71 home -> deleof
  434.               dw      0               ;72 up
  435.               dw      1               ;73 pgup null
  436.               dw      0               ;74 -
  437.               dw      0               ;75 left
  438.               dw      1               ;76 center -> null
  439.               dw      0               ;77 right
  440.               dw      0               ;78 +
  441. resetkey      dw      4f00h           ;79 end -> reset
  442.               dw      0               ;80 down
  443.               dw      1               ;81 pgdn -> null
  444.               dw      0               ;82 ins
  445.               dw      0               ;83 del
  446.               dw      86-84+1 dup(1)  ;84-86 -> null
  447.               dw      8200h, 8300h    ;87-88 f11,12
  448. ;.................................................
  449.  
  450. ctltbl:
  451.               dw      0               ;1=esc (Windows)
  452.               dw      8500h, 8600h    ;2-13 (digits-=) -> pf13-24
  453.               dw      8700h, 8800h
  454.               dw      8900h, 8a00h
  455.               dw      8b00h, 8c00h
  456.               dw      8d00h, 8e00h
  457.               dw      8f00h, 9000h
  458.               dw      0               ;14 bsp
  459. backtab       dw      0f00h           ;15 ^tab -> backtab
  460.               dw      27-16+1 dup(0)  ;16-27
  461.               dw      4e00h           ;28 enter -> newline
  462.               dw      58-29+1 dup(0)  ;29-58
  463.               dw      8500h, 8600h    ;59-68 f1-10 -> pf13-22
  464.               dw      8700h, 8800h    ;
  465.               dw      8900h, 8a00h    ;
  466.               dw      8b00h, 8c00h    ;
  467.               dw      8d00h, 8e00h    ;
  468.               dw      86-69+1 dup(1)  ;69-86
  469.               dw      8f00h, 9000h    ;87-88 f11,12 -> pf23,24
  470. ;.................................................
  471.  
  472. alttbl:
  473.               dw      1               ;1 esc -> null
  474.               dw      7800h, 7900h    ;2-13 (digits-=) -> pf1-12
  475.               dw      7a00h, 7b00h
  476.               dw      7c00h, 7d00h
  477.               dw      7e00h, 7f00h
  478.               dw      8000h, 8100h
  479.               dw      8200h, 8300h
  480.               dw      27-14+1 dup(0)  ;14-27
  481.               dw      4e00h           ;28 enter -> newline
  482.               dw      66-29+1 dup(0)  ;29-66
  483.               dw      7000h           ;67-69 f9   pa1
  484.               dw      7100h           ;      f10  pa2
  485.               dw      7200h           ;      f11  pa3
  486.               dw      88-70+1 dup(1)  ;70+
  487. ;-------------------------------------------------
  488.  
  489.               ;check table len
  490.               if      ($-plaintbl) / 2 - (3*88)
  491.               .err
  492.               endif
  493. ;--------------------------------------------------
  494. ;--------------------------------------------------
  495.  
  496. newint9:
  497.               ;kb int handler
  498.               cli
  499.               pushf
  500.               push    ax
  501.               push    bx
  502.               push    cx
  503.               push    dx
  504.               push    si
  505.               push    di
  506.               push    ds
  507.               push    es
  508.               push    bp
  509.               mov     ds, cs:cseg
  510.  
  511.               ;fix bios bug
  512.               mov     al, 0adh        ;disable kb
  513.               call    outkb
  514.  
  515.               sti                     ;enable higher ints
  516.               in      al, 60h         ;get scancode
  517.               jmp     $+2
  518.  
  519.               mov     ah, prevscan +1 ;prev key
  520.               mov     prevscan, ah
  521.               mov     prevscan+1, al  ;this key
  522.               xor     ah, ah
  523.  
  524.               test    al, 80h         ;break etc.
  525.               jmpne   jbios           ;yes- ignore
  526.  
  527.               ;get shift state
  528.               mov     es, bioseg
  529.               mov     cl, es:kbflag
  530.  
  531.               ;test for hotkey
  532.               cmp     al, 42          ;left-shift
  533.               jne     @f              ;no
  534.               test    cl, 1           ;right-shift pending
  535.               jnz     hotyes          ;yes
  536.               jmp     short jbios
  537. @@:
  538.               cmp     al, 54          ;right-shift
  539.               jne     nothot          ;no
  540.               test    cl, 2           ;left shift pending
  541.               jz      jbios           ;no
  542. hotyes:
  543.               ;hotkey pressed
  544.               cmp     jxactive, 0     ;active
  545.               jne     @f              ;yes
  546.               mov     pop_request, 18 ;pop
  547.               jmp     done9
  548. @@:
  549.               inc     popoutsw
  550.               jmp     done9
  551. nothot:
  552.               cmp     jxactive, 0     ;are we active
  553.               je      jbios           ;no- done
  554.  
  555.               ;passthru if numlok+ keypad (digit)
  556.               test    cl, 20h         ;numlok on
  557.               jz      @f              ;no
  558.               cmp     prevscan, 0e0h  ;extended (negates numlok)
  559.               je      @f              ;yes
  560.               cmp     al, 71          ;keypad
  561.               jb      @f              ;no
  562.               cmp     al, 83
  563.               jna     jbios           ;yes- transparent
  564. @@:
  565.               ;the only shift translation is shift-tab to backtab.
  566.               test    cl, 3           ;shifted
  567.               jz      noshift         ;no
  568.               cmp     al, 15          ;tab
  569.               jne     jbios           ;no
  570.               mov     bx, backtab
  571.               jmp     short stuff_bx
  572. noshift:
  573.               ;set bx to correct shift-state lookup tbl
  574.               mov     bx, offset plaintbl  ;assume no state
  575.               test    cl, 8           ;alt mask
  576.               jz      noalt           ;no
  577.               mov     bx, offset alttbl
  578. noalt:
  579.               test    cl, 4           ;ctl mask
  580.               jz      @f              ;no
  581.               mov     bx, offset ctltbl
  582. @@:
  583.               ;get replacement char
  584.               mov     si, ax
  585.               shl     si, 1
  586.               mov     bx, [bx] [si] -2  ;fetch replacement
  587.               cmp     bx, 1           ; 0=transparent (pass to bios)
  588.               je      done9           ; 1=nul
  589.               ja      stuff_bx        ; else replace
  590. jbios:
  591.               ;pass to bios
  592.               pop     bp
  593.               pop     es
  594.               pop     ds
  595.               pop     di
  596.               pop     si
  597.               pop     dx
  598.               pop     cx
  599.               pop     bx
  600.               pop     ax
  601.               call    dword ptr cs:oldint9
  602.               push    ax
  603.               mov     al, 0aeh        ;enable kb
  604.               call    outkb
  605.               pop     ax
  606.               iret
  607. stuff_bx:
  608.               cmp     bx, resetkey    ;reset key
  609.               jne     @f              ;no
  610.               inc     resetsw         ;set priority switch
  611.               jmp     short done9     ;ignore key
  612. @@:
  613.               mov     ax, bx
  614.               cmp     bh, 83h         ;bios max
  615.               jna     @f
  616.               push    bx
  617.               mov     ax, 1515h       ;special prefix code (see getkey)
  618.               call    stuffchar       ;(does sti)
  619.               pop     ax
  620.               xchg    ah, al          ;reversed extended code
  621. @@:
  622.               call    stuffchar       ;(does sti)
  623. done9:
  624.               pop     bp
  625.               pop     es
  626.               pop     ds
  627.               pop     di
  628.               pop     si
  629.               pop     dx
  630.               pop     cx
  631.               pop     bx
  632.               cli
  633.  
  634.               ;enable kb
  635.               mov     al, 0aeh        ;enable kb
  636.               call    outkb
  637.  
  638.               ;clear kb int
  639.               in      al, 61h
  640.               jmp     $+2
  641.               or      al, 80h
  642.               out     61h, al         ;set hi
  643.               jmp     $+2
  644.               and     al, not 80h
  645.               out     61h, al         ;set lo
  646.               jmp     $+2
  647.  
  648.               ;eoi
  649.               mov     al, 20h
  650.               out     20h, al
  651.               jmp     $+2
  652.  
  653.               pop     ax
  654.               popf
  655.               iret
  656. ;--------------------------------------------------
  657.  
  658. outkb:
  659.               ;this helps avoid a bios bug
  660.               push    ax
  661. @@:           in      al, 64h
  662.               jmp     $+2
  663.               test    al, 2
  664.               jnz     @b
  665.               pop     ax
  666.               out     64h, al
  667.               jmp     $+2
  668.               ret
  669. ;--------------------------------------------------
  670.  
  671. stuffchar:
  672.               ;stuff ax into kbbuf
  673.               ;es = bios
  674.               cli
  675.               mov     bx, es:kbtail   ;next open loc
  676.               add     bx, 2           ;new tail
  677.               cmp     bx, kbend       ;wrap
  678.               jne     @f              ;no
  679.               mov     bx, kbstart
  680. @@:           cmp     bx, es:kbhead   ;new tail = head
  681.               je      @f              ;yes- no room for more- abandon
  682.               xchg    es:kbtail, bx   ;new tail
  683.               mov     es:[bx], ax     ;add char
  684. @@:
  685.               sti
  686.               ret
  687. ;-----------------------------------------------------------
  688.  
  689. delayx:
  690.               ;delay ax tiks. (55ms, 18.2 tiks per second)
  691.               call    start_tmo
  692. @@:           call    tst_tmo
  693.               jnc     @b
  694.               ret
  695. ;------------------------------------------------------------
  696.  
  697. start_tmo:
  698.               ;initialize tmo counter
  699.               push    ax
  700.               push    es
  701.               mov     es, bioseg
  702.               mov     ax, es:[6ch]    ;timer lo
  703.               mov     tmodd, ax
  704.               mov     ax, es:[6eh]    ;timer hi
  705.               mov     tmodd +2, ax
  706.               pop     es
  707.               pop     ax
  708.               ret
  709. ;------------------------------------------------------------
  710.  
  711. tst_tmo:
  712.               ;stc if ax tiks have elapsed since last call to start-tmo
  713.               push    ax
  714.               push    bx
  715.               push    cx
  716.               push    dx
  717.  
  718.               mov     bx, ax
  719.  
  720.               push    es
  721.               mov     es, bioseg
  722.               mov     cx, es:[6ch]    ;timer lo
  723.               mov     ax, es:[6eh]    ;timer hi
  724.               pop     es
  725.  
  726.               ;get init-val plus interval
  727.               mov     dx, tmodd +2    ;hi
  728.               add     bx, tmodd
  729.               jnc     @f              ;no lo wrap
  730.               add     dx, 1           ;(don't inc)
  731.               jnc     @f              ;no num wrap
  732.  
  733.               ;deadline is a wrap.
  734.               cmp     dx, ax          ;deadline, current hi
  735.               jne     timex           ;no timeout
  736.               cmp     bx, cx          ;deadline, current lo
  737.               ja      timex
  738.               jmp     short timeout   ;timeout
  739. @@:           cmp     dx, ax          ;deadline, current hi
  740.               ja      timex           ;no timeout
  741.               cmp     bx, cx          ;lo
  742.               ja      timex           ;no timeout
  743. timeout:
  744.               stc
  745.               jmp     short timez
  746. timex:
  747.               clc
  748. timez:
  749.               pop     dx
  750.               pop     cx
  751.               pop     bx
  752.               pop     ax
  753.               ret
  754. ;--------------------------------------------------
  755. clrscr:
  756.               xor     dx, dx
  757.               call    curpos
  758.               mov     cx, 25*80
  759.               jmp     short clr_area
  760. ;.....................................
  761. clr_area:
  762.               ;write cx blanks at dx
  763.               push    es
  764.               push    cx
  765.               call    get_dxaddr
  766.               pop     cx
  767.               mov     al, ' '
  768.               inc     areasw
  769.               call    vidchar
  770.               pop     es
  771.               ret
  772. ;--------------------------------------------------
  773.  
  774. show_cx_cursor:
  775.               cmp     adapter, 2      ;ega active
  776.               jne     @f              ;no
  777.               test    cx, 80h         ;use ega emulation
  778.               jnz     @f              ;yes
  779.               push    es
  780.               mov     es, bioseg
  781.               push    word ptr es:ega_info  ;save ega info byte
  782.               or      byte ptr es:ega_info, 1  ;disable ega cursor emulation
  783.               mov     ah, 1           ;set cx cursor style
  784.               int     10h
  785.               pop     word ptr es:ega_info  ;restore ega info byte
  786.               pop     es
  787.               ret
  788. @@:
  789.               and     cx, not 80h
  790.               mov     ah, 1           ;set cx cursor style
  791.               int     10h
  792.               ret
  793. ;--------------------------------------------------
  794.  
  795. curpos:
  796.               ;set real and virtual cursor pos from dx
  797.               mov     curloc, dx
  798.               push    ax
  799.               push    bx
  800.               mov     ah, 2           ;set dx pos
  801.               mov     bh, vid_page
  802.               int     10h
  803.               pop     bx
  804.               pop     ax
  805.               ret
  806. ;--------------------------------------------------
  807.  
  808. tty2:
  809.               ;write al char at curloc. bump curloc.
  810.               ;preserve all regs
  811.  
  812.               push    ax
  813.               push    cx
  814.               push    di
  815.               push    si
  816.               push    es
  817.  
  818.               ;compute buffer offset
  819.               push    ax              ;char
  820.               call    get_vidaddr
  821.               pop     ax
  822.  
  823.               call    vidchar         ;store
  824.               inc     curloc
  825.               cmp     byte ptr curloc, 80
  826.               jb      @f
  827.               mov     byte ptr curloc, 0
  828.               inc     byte ptr curloc+1
  829. @@:           pop     es
  830.               pop     si
  831.               pop     di
  832.               pop     cx
  833.               pop     ax
  834.               ret
  835. ;--------------------------------------------------
  836.  
  837. get_dxaddr:
  838.               mov     curloc, dx
  839. get_vidaddr:
  840.               ;curloc to es:di
  841.               push    ax
  842.               push    cx
  843.               mov     al, byte ptr curloc+1  ;line x 160
  844.               mov     cx, 160
  845.               mul     cl
  846.               mov     cl, byte ptr curloc  ;col x 2
  847.               shl     cl, 1
  848.               add     ax, cx          ;offset in page
  849.               xor     di, di
  850.               cmp     ax, 25*160      ;4,000
  851.               ja      @f
  852.               mov     di, ax          ;to
  853. @@:           mov     cl, vid_page
  854.               jcxz    @f              ;save time
  855.               mov     ax, 1000h       ;4k pages in 80 col mode
  856.               mul     cl              ;page offset
  857.               add     di, ax          ;total offset
  858. @@:           mov     es, vidseg
  859.               pop     cx
  860.               pop     ax
  861.               ret
  862. ;--------------------------------------------------
  863.  
  864. vidchar:
  865.               stosb
  866.               inc     di
  867.               cmp     areasw, 0
  868.               je      @f
  869.               dec     cx
  870.               jnz     vidchar
  871.               mov     areasw, cl
  872. @@:           ret
  873. ;--------------------------------------------------
  874. ;--------------------------------------------------
  875.  
  876.               ;timer and popup
  877.  
  878.               assume  ds:nothing  ;for ints and popup
  879. newint8:
  880.               ;timer int
  881.               cli
  882.               pushf
  883.               call    dword ptr oldint8  ;also does eoi
  884.  
  885.               cmp     popped, 0       ;is anybody pending or popped
  886.               je      @f              ;no
  887.               iret
  888. @@:           inc     popped          ;busy now
  889.               sti
  890.               cld
  891.  
  892.               ;regs have not been saved
  893.  
  894.               cmp     unloadsw, 2     ;unloading
  895.               je      @f              ;yes
  896.               cmp     pop_request, 0  ;pop requested
  897.               je      exit8           ;no
  898. @@:
  899.               cmp     busy10, 0       ;video busy
  900.               jne     bad8            ;yes- exit with prejudice
  901.               cmp     busy13, 0       ;disk busy
  902.               jne     bad8            ;yes- exit with prejudice
  903.  
  904.               push    es
  905.               push    di
  906.               mov     es, dos_seg     ;indos seg (usually)
  907.               mov     di, indosaddr
  908.               cmp     byte ptr es:[di], 0  ;dos busy
  909.               jne     xp              ;yes- exit with prejudice
  910.               mov     di, critaddr    ;in critical error
  911.               cmp     byte ptr es:[di], 0
  912.               jne     xp              ;yes- exit with prejudice
  913.               mov     pop_request, 0
  914.               call    popup
  915.               mov     pop_request, 1  ;going to 0
  916. xp:
  917.               pop     di
  918.               pop     es
  919. bad8:
  920.               dec     pop_request
  921. exit8:
  922.               cli
  923.               mov     popped, 0
  924.               iret
  925. ;-----------------------------------------------------------------------
  926.  
  927.               ;assume  ds:nothing ..cont
  928. newint28:
  929.               ;idle int
  930.               ;note regs are not saved until popup
  931.  
  932.               cli
  933.               pushf
  934.               call    dword ptr oldint28
  935.  
  936.               cmp     popped, 0       ;is anybody popped
  937.               je      @f              ;no
  938.               iret
  939. @@:           inc     popped          ;busy now
  940.               sti
  941.               cld
  942.  
  943.               cmp     pop_request, 0  ;pop requested
  944.               je      exit28          ;no- exit
  945.               cmp     busy10, 0       ;video busy
  946.               jne     exit28          ;yes- exit
  947.               cmp     busy13, 0       ;disk busy
  948.               jne     exit28          ;yes- exit
  949.  
  950.               push    es
  951.               push    di
  952.               mov     es, dos_seg     ;in critical error
  953.               mov     di, critaddr
  954.               cmp     byte ptr es:[di], 0
  955.               pop     di
  956.               pop     es
  957.               mov     pop_request, 0
  958.               jne     exit28          ;yes
  959.               call    popup
  960. exit28:
  961.               cli
  962.               mov     popped, 0
  963.               iret
  964. ;-----------------------------------------------------------
  965.  
  966.               ;assume  ds:nothing ..cont
  967. popup:
  968.               mov     savess, ss   ;save caller's stack
  969.               mov     savesp, sp
  970.               cli                     ;new stack
  971.               push    cs
  972.               pop     ss
  973.               mov     sp, offset stackend
  974.               sti
  975.               mypusha
  976. ;.........................................................
  977.  
  978.               mov     ds, cs:cseg
  979.               assume  ds:code         ; es is not set
  980. ;.........................................................
  981.  
  982.               ;test for uninstall
  983.               cmp     unloadsw, 2
  984.               jne     @f              ;no
  985.               esds
  986.               call    remove          ;disable and unvector
  987.               mov     es, mypsp
  988.               mov     cx, es:[2ch]    ;envir blok
  989.               push    cx              ;save
  990.               mov     ah, 49h         ;release pgm
  991.               mov     es, mypsp
  992.               int     21h
  993.               pop     es              ;envir
  994.               mov     ah, 49h         ;release envir
  995.               int     21h
  996.               jmp     short popexit
  997. @@:
  998.               call    ck_vid          ;mode ok to pop
  999.               jnc     pop20           ;yes
  1000. ;................
  1001. popexit:
  1002.               ;return to interrupted application
  1003.               cmp     unloadsw, 1
  1004.               jne     @f
  1005.               inc     unloadsw
  1006. @@:
  1007.               mypopa
  1008.               mov     ss, cs:savess
  1009.               mov     sp, cs:savesp
  1010.               ret                     ;back to int8,int28
  1011. ;................
  1012. pop20:
  1013.               ;we are active
  1014.               inc     jxactive        ;we're active
  1015.               esds
  1016.               jmp     restart
  1017. ;.....................................................
  1018. popout:
  1019.               ;return to interrupted pgm (jumped-to)
  1020.  
  1021.               call    popscr2         ;restore as when called
  1022.               call    clr_kb
  1023.  
  1024.               mov     jxactive, 0
  1025.               jmp     popexit
  1026. ;-----------------------------------------------------------
  1027.  
  1028. newint2f:
  1029.               ; entry: ah - device id
  1030.               pushf
  1031.               cmp     ah, muxid
  1032.               je      @f              ;its us
  1033.               popff
  1034.               jmp     dword ptr cs:oldint2f
  1035. @@:
  1036.               push    ds
  1037.               push    cs
  1038.               pop     ds
  1039.               mov     al, -1          ;indicate installed
  1040.               cmp     bx, 0202h       ;called to pop (nu)
  1041.               jne     @f              ;no
  1042.               mov     pop_request, 26
  1043. @@:
  1044.               cmp     bx, 0303h       ;called to uninstall
  1045.               jne     fx              ;no
  1046.               call    ckvec           ;are we last on all vectors
  1047.               jnc     @f              ;yes
  1048.               mov     al, 7           ;beep
  1049.               int     29h
  1050.               jmp     short fx
  1051. @@:           mov     unloadsw, 2
  1052. fx:
  1053.               push    cs              ;returns es = installed segment
  1054.               pop     es
  1055.               pop     ds
  1056.               popff
  1057. iiret:        iret
  1058. ;---------------------------------------------------------
  1059.  
  1060. ckvec:
  1061.               ;stc if any ints have been intercepted since we loaded
  1062.               mov     al, 8
  1063.               call    cksub
  1064.               jne     @f
  1065.               mov     al, 9
  1066.               call    cksub
  1067.               jne     @f
  1068.               mov     al, 28h
  1069.               call    cksub
  1070.               jne     @f
  1071.               mov     al, 2fh
  1072.               call    cksub
  1073.               jne     @f
  1074.               clc
  1075.               ret
  1076. @@:
  1077.               stc
  1078.               ret
  1079. ;.........................................................
  1080.  
  1081. cksub:
  1082.               push    es
  1083.               mov     ah, 35h
  1084.               int     21h
  1085.               mov     ax, es
  1086.               cmp     ax, cseg
  1087.               pop     es
  1088.               ret
  1089. ;---------------------------------------------------------
  1090.  
  1091. remove:
  1092.               push    ds
  1093.               assume  ds:nothing
  1094.               lds     dx, dword ptr oldint8
  1095.               mov     ax, 2508h
  1096.               int     21h
  1097.  
  1098.               lds     dx, dword ptr oldint9
  1099.               mov     ax, 2509h
  1100.               int     21h
  1101.  
  1102.               lds     dx, dword ptr oldint28
  1103.               mov     ax, 2528h
  1104.               int     21h
  1105.  
  1106.               lds     dx, dword ptr oldint2f
  1107.               mov     ax, 252fh
  1108.               int     21h
  1109.  
  1110.               pop     ds
  1111.               assume  ds:code
  1112.               ret
  1113. ;------------------------------------------------------------
  1114.  
  1115. ck_vid:
  1116.               mov     ah, 0fh
  1117.               int     10h             ;get cols,mode,page
  1118.               cmp     al, 2           ;2,3,7 ok (all are 80 col)
  1119.               je      @f
  1120.               cmp     al, 3
  1121.               je      @f
  1122.               cmp     al, 7
  1123.               je      @f
  1124.               stc                     ;no
  1125.               ret
  1126. @@:           mov     vid_page, bh
  1127.               clc
  1128.               ret
  1129. ;------------------------------------------------------------
  1130. ;------------------------------------------------------------
  1131.  
  1132.               ;final section of resident code
  1133.               ;this allocation method minimizes the .com size
  1134.  
  1135.               even
  1136. mystack       equ     $        ;stack 512
  1137.   stackend    equ     mystack  +512 -2
  1138. progend       equ     mystack  +512
  1139. ;------------------------------------------------------------
  1140.  
  1141. install:
  1142.               ;end of resident code
  1143.               ;one-time init code
  1144.  
  1145.               mov     ax, cs
  1146.               mov     ds, ax
  1147.               mov     mypsp, es
  1148.               mov     es, ax
  1149.               mov     ss, ax
  1150.               mov     sp, offset stackend
  1151.               mov     cseg, ax
  1152.               cld
  1153.  
  1154.               call    getcmd          ;get cmdline parms
  1155.               cmp     uninsw, 0       ;request to uninstall
  1156.               je      @f              ;no
  1157.               mov     ah, muxid
  1158.               xor     al, al
  1159.               mov     bx, 0303h
  1160.               int     2fh
  1161.               mov     ax, 4c00h       ;eoj
  1162.               int     21h
  1163. @@:
  1164.               call    getvid          ;get display info
  1165.               call    revec           ;setup intercepts
  1166.  
  1167.               ;get dos version
  1168.               mov     ah, 30h
  1169.               xor     al, al
  1170.               int     21h
  1171.               xchg    ah, al
  1172.               mov     dos_version, ax
  1173.  
  1174.               ;set kbstart,end
  1175.               mov     ax, offset kbbuf
  1176.               mov     bx, offset kbbuf+32
  1177.               mov     kbstart, ax
  1178.               mov     kbend, bx
  1179.  
  1180.               ;get cursor offset for 2,2
  1181.               ;(first char of each line is an attrib char)
  1182.               mov     ax, 25          ;convert row,col to offset
  1183.               mov     dh, 2
  1184.               mov     dl, 2
  1185.               apicall
  1186.               mov     dataloc, ax     ;save
  1187.  
  1188.               ;display msg
  1189.               mov     ah, 9
  1190.               laddr   dx, <'JX Installed.$'>
  1191.               int     21h
  1192.  
  1193.               ;adj pgm size
  1194.               mov     ax, 4a00h
  1195.               mov     bx, (progend-code +15) shr 4
  1196.               mov     es, mypsp
  1197.               int     21h
  1198.  
  1199.               ;go resident
  1200.               mov     ax, 3100h       ;tsr
  1201.               mov     dx, (progend-code +15) shr 4
  1202.               int     21h
  1203. ;--------------------------------------------------
  1204.  
  1205. getvid:
  1206.               ;get video segment addr
  1207.               ;set adapter type
  1208.  
  1209.               mov     es, bioseg
  1210.               mov     ax, es:addr_crtc
  1211.               mov     crtc, ax
  1212.  
  1213.               mov     ah, 12h         ;get ega,vga info
  1214.               mov     bl, 10h
  1215.               int     10h
  1216.               cmp     bl, 10h         ;did bl return unchanged
  1217.               je      vid20           ;yes- no ega,vga
  1218.               mov     es, bioseg
  1219.               test    es:ega_info, 8  ;ega currently active
  1220.               jnz     vid20           ;no
  1221.               mov     adapter, 2      ;active ega
  1222.               mov     vidseg, 0b800h  ;color
  1223.               push    bx
  1224.               mov     ax, 1130h       ;get nof scan lines per char
  1225.               int     10h             ;to create new shape
  1226.               dec     cl
  1227.               mov     ch, cl
  1228.               sub     ch, 2
  1229.               mov     my_style, cx
  1230.               pop     bx
  1231.               or      bh, bh          ;ega attached to color monitor
  1232.               je      vid40           ;yes
  1233.               mov     vidseg, 0b000h  ;mono
  1234.               jmp     short vid40
  1235.  
  1236.               ;cga or mda.
  1237. vid20:        test    crtc, 40h       ;mono
  1238.               jz      @f              ;yes
  1239.               mov     adapter, 1      ;cga
  1240.               mov     my_style, 0607h
  1241.               mov     vidseg, 0b800h  ;color
  1242.               jmp     short vid40
  1243. @@:           mov     adapter, 0      ;mda
  1244.               mov     my_style, 0b0ch
  1245.               mov     vidseg, 0b000h  ;mono
  1246. vid40:
  1247.               esds
  1248.               ret
  1249. ;--------------------------------------------------
  1250.  
  1251. revec:
  1252.               ;see if already resident in memory.  dos 3.0+ only
  1253.               not     word ptr [begin] ;no match on this copy
  1254.               mov     ah, muxid
  1255.               xor     al, al
  1256.               int     2fh             ;sets es = installed seg
  1257.               or      al, al
  1258.               jz      nodup           ;not found
  1259.               mov     si, offset begin ;tst signature also
  1260.               mov     di, si
  1261.               mov     cx, 16
  1262.               repe    cmpsb
  1263.               jne     nodup
  1264.  
  1265.               laddr   dx, <'Already installed$'>
  1266.               mov     ah, 9
  1267.               int     21h
  1268.               mov     ax, 4c01h       ;eoj
  1269.               int     21h
  1270. ;.....................
  1271. nodup:
  1272.               ;get dos-seg and indos addr at es:bx
  1273.               mov     ah, 34h
  1274.               int     21h
  1275.               mov     dos_seg, es
  1276.               mov     indosaddr, bx
  1277.  
  1278.               ;get critical err addr
  1279.               mov     ax, 3e80h       ;cmp opcode
  1280.               mov     cx, 2000h       ;max search length
  1281.               mov     di, bx          ;start at indos address
  1282. @@:           repne   scasw           ;do the search
  1283.               jcxz    @f              ;branch if search failed
  1284.               cmp     byte ptr es:[di+5], 0bch  ;verify this is it
  1285.               je      found           ;yes
  1286.               jmp     @b
  1287. @@:           mov     cx, 2000h       ;search again
  1288.               inc     bx              ;search odd addresses this time
  1289.               mov     di, bx
  1290. @@:           repne   scasw           ;look for the opcode
  1291.               jcxz    @f              ;not found
  1292.               cmp     byte ptr es:[di+5], 0bch  ;verify
  1293.               je      found
  1294.               jmp     @b
  1295. @@:
  1296.               laddr   dx, <'DOS flag not found$'>
  1297.               mov     ah, 9
  1298.               int     21h
  1299.               mov     ax, 4c01h
  1300.               int     21h
  1301.               nop
  1302. found:        mov     ax, es:[di]     ;get flag offset address
  1303.               mov     critaddr, ax
  1304.  
  1305. ;.....................
  1306.               mov     ax, 3508h       ;timer tik
  1307.               int     21h
  1308.               mov     oldint8, bx
  1309.               mov     oldint8 +2, es
  1310.               mov     ax, 2508h
  1311.               mov     dx, offset newint8
  1312.               int     21h
  1313.  
  1314.               mov     ax, 3509h       ;kb int
  1315.               int     21h
  1316.               mov     oldint9, bx
  1317.               mov     oldint9 +2, es
  1318.               mov     ax, 2509h
  1319.               mov     dx, offset newint9
  1320.               int     21h
  1321.  
  1322.               mov     ax, 3528h       ;idle
  1323.               int     21h
  1324.               mov     oldint28, bx
  1325.               mov     oldint28 +2, es
  1326.               mov     ax, 2528h
  1327.               mov     dx, offset newint28
  1328.               int     21h
  1329.  
  1330.               mov     ax, 352fh       ;multiplex
  1331.               int     21h
  1332.               mov     oldint2f, bx
  1333.               mov     oldint2f +2, es
  1334.               mov     ax, 252fh
  1335.               mov     dx, offset newint2f
  1336.               int     21h
  1337.  
  1338.               esds
  1339.               ret
  1340. ;----------------------------------------------------------
  1341.  
  1342.               ;..revector
  1343. getcmd:
  1344.               ;cmd tail tests
  1345.               assume  ds:nothing
  1346.               mov     ds, mypsp
  1347. ;.............
  1348.               ;test for cmdline /U  to uninstall
  1349.               mov     si, 81h
  1350. @@:           lodsb
  1351.               cmp     al, 13
  1352.               je      @f
  1353.               or      al, 20h
  1354.               cmp     al, 'u'
  1355.               jne     @b
  1356.               cmp     byte ptr [si-2], '/'
  1357.               jne     @b
  1358.               inc     uninsw
  1359. @@:
  1360. ;.............
  1361.               mov     ds, cs:cseg
  1362.               assume  ds:code
  1363.               ret
  1364. ;------------------------------------------------------------
  1365.  
  1366. code          ends
  1367.               end     begin
  1368.